package dao;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * JDK动态代理：通过被代理对象实现的接口产生其代理对象；
 * （1）创建一个类，实现InvocationHandler接口，重写invoke方法；
 * （2）在类中定义一个Object类型的变量，并提供这个变量的有参构造器，用于将被代理对象传进来；
 * （3）定义getProxy方法，用于创建并返回代理对象；
 **/
public class JDKDynamicProxy implements InvocationHandler {

    //被代理对象
    private Object object;

    public JDKDynamicProxy(Object object) {
        this.object = object;
    }

    //产生代理对象，返回代理对象
    public Object getProxy() {

        //1、获取被代理对象的类加载器；
        ClassLoader classLoader = object.getClass().getClassLoader();

        //2、获取被代理对象的实现接口；
        Class<?>[] interfaces = object.getClass().getInterfaces();

        //3、产生代理对象(通过被代理对象的类加载器和实现的接口)
        //第一个参数：被代理对象的类加载器；
        //第二个参数：被代对象实现的接口；
        //第三个参数：使用产生代理对象的调用方法时，用于拦截方法执行的处理器；回调方法
//        Object o = Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {
//            @Override
//            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//                return null;
//            }
//        });

        //当前类已经实现了invoke方法，使用this。
        Object proxy = Proxy.newProxyInstance(classLoader, interfaces, this);
        return proxy;
    }

    //让当前的类实现InvocationHandler
    //Method为传入的方法名字，Object[]为传放入方法的参数；
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        begin();
        //执行method的方法
        //Object returnValue = method.invoke(object);
        Object returnValue = method.invoke(object, args);
        commit();
        return returnValue;
    }

    public void begin() {
        System.out.println("开启事务");
    }

    public void commit() {
        System.out.println("提交事务");
    }


}
